<template>
    <div class="full-calendar-header">
      <div class="header-left">
        <slot name="header-left"></slot>
      </div>
      <div class="header-center">
        <a-month-picker
          v-model="headDate"
          type="month"
          placeholder="选择月"
          value-format="yyyy-MM"
          allow-clear="false"
          @change="changeMonthDay"
          style="font-size: 16px;font-weight: bold;">
        </a-month-picker>
        <a-button class="to-today" type="primary" plain @click="toDate">本月</a-button>
      </div>
      <div class="header-right">
        <slot name="header-right"></slot>
      </div>
    </div>
  </template>
  
  <script lang="ts" setup>
  import { ref, onMounted, watch } from 'vue';
  import * as dateFunc from '../utils/dateFunc';

  const emit = defineEmits<{
      (
        event: 'change',
        startDateStr: string,
        endDateStr: string,
        currentDateStr: string,
        headDate: Date
      ): void;
    }>();
  
  // 定义 props 类型
  interface Props {
    currentDate: any;
    titleFormat: any;
    firstDay: any;
    monthNames: any;
  }
  
  const props = withDefaults(defineProps<Props>(), {});
  
  // 定义状态
  const title = ref('');
  const leftArrow = ref('<');
  const rightArrow = ref('>');
  const headDate = ref(new Date());
  const nowMonth = ref(new Date());
  // 组件挂载时触发事件分发
  onMounted(() => {
    dispatchEvent();
  });
  
  // 监听 currentDate 变化
  watch(() => props.currentDate, (val) => {
    if (!val) return;
    headDate.value = val;
  });
  
  // 回到当前月
  const toDate = () => {
    headDate.value = new Date();
    nowMonth.value = new Date();
    dispatchEvent();
  };
  
  // 切换到上一个月
  const goPrev = () => {
    headDate.value = changeMonth(headDate.value, -1);
    dispatchEvent();
  };
  
  // 切换到下一个月
  const goNext = () => {
    headDate.value = changeMonth(headDate.value, 1);
    dispatchEvent();
  };
  
  // 改变月份
  const changeMonth = (date: Date, num: number) => {
    let dt = new Date(date);
    return new Date(dt.setMonth(dt.getMonth() + num));
  };
  
  // 触发事件分发
  const dispatchEvent = () => {
    title.value = dateFunc.format(headDate.value, props.titleFormat, props.monthNames);
  
    let startDate = dateFunc.getStartDate(headDate.value);
    let curWeekDay = startDate.getDay();
  
    // 1st day of this monthView
    let diff = parseInt(String(props.firstDay)) - curWeekDay;
    if (diff) diff -= 7;
    startDate.setDate(startDate.getDate() + diff);
  
    // the month view is 6*7
    let endDate = dateFunc.changeDay(startDate, 41);
  
    // 1st day of current month
    let currentDate = dateFunc.getStartDate(headDate.value);
    emit(
      'change',
      dateFunc.format(startDate, 'yyyy-MM-dd', null),
      dateFunc.format(endDate, 'yyyy-MM-dd', null),
      dateFunc.format(currentDate, 'yyyy-MM-dd', null),
      headDate.value
    );
  };
  
  // 改变选择的月份
  const changeMonthDay = (dateString, date) => {
    headDate.value = new Date(date);
    dispatchEvent();
  };
  </script>
  
  <style lang="scss">
  .full-calendar-header {
    display: flex;
    align-items: center;
  
    .header-left,
    .header-right {
      flex: 1;
    }
  
    .header-center {
      flex: 3;
      text-align: center;
      font-size: 18px;
  
      .to-today {
        margin-left: 30px;
      }
  
      .title {
        margin: 0 10px;
      }
  
      .prev-month,
      .next-month {
        cursor: pointer;
      }
    }
  }
  </style>    